﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using Org.BouncyCastle.Asn1.X509;
using SealManagement.Common;
using SealManagement.Extensions;
using SealManagement.Models;
using SealManagement.SqlData;

namespace SealManagement.Controllers
{

    public class ProduceSignController : Controller
    {
        private SignContext _context;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        public ProduceSignController(SignContext context)
        {
            _context = context;
        }
        public IActionResult Index()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }

        [Authorize(Roles = "User")]
        [HttpPost]
        public async Task<IActionResult> Index(int PageSize = 10, int PageIndex = 1)
        {
            var total = 0;
            try
            {
                var produceSignList = _context.ProduceSigns?
                .Skip(PageSize * (PageIndex - 1)).Take(PageSize)
                //.ToListAsync()
                .Select(s => new
                {
                    s.Id,
                    s.MakerCertBase64,
                    s.MakerCertSN,
                    s.SealBase64,
                    s.SealName,
                    s.SealType,
                    s.StartTime,
                    s.EndTime,
                    s.UserCertBase64,
                    s.UserCertSN,
                    s.SealImage,
                    //SealImg = Convert.ToBase64String(GMSealInfo.DecodeGMSeal(Convert.FromBase64String(s.SealBase64)).ImageBytes),
                    MakerDN = $"CN = {new Org.BouncyCastle.X509.X509CertificateParser().ReadCertificate(Convert.FromBase64String(s.MakerCertBase64)).SubjectDN.GetValueList(X509Name.CN)[0].ToString()},C=CN",
                    UserDN = $"CN = {new Org.BouncyCastle.X509.X509CertificateParser().ReadCertificate(Convert.FromBase64String(s.UserCertBase64)).SubjectDN.GetValueList(X509Name.CN)[0].ToString()},C=CN",
                    // var certParser = new Org.BouncyCastle.X509.X509CertificateParser();
                    //var retCert = certParser.ReadCertificate(cert.RawData);
                    //var alias = retCert.SubjectDN.GetValueList(X509Name.CN)[0].ToString();
                    //ViewData["CertStr"] = $"CN={alias},C=CN";
                    IsAudit = s.IsAudit == 0 ? "未审核" : (s.IsAudit == 1 ? "已审核" : (s.IsAudit == 2 ? "已冻结" : "审核失败"))
                });
                total = _context.ProduceSigns.Count();
                return Json(new
                {
                    state = resultType.Success,
                    data = produceSignList,
                    total = total
                });
            }
            catch (Exception e)
            {
                return Json(new
                {
                    state = resultType.Error,
                    message = $"获取印章信息列表失败，{e.Message}",
                    total = total
                });
            }

        }

        [Authorize(Roles = "SignMaker")]
        /// <summary>
        /// 制章
        /// </summary>
        /// <returns></returns>
        public IActionResult Create()
        {
            //返回当前制章人序列号用于验证
            var signMakerId = User.FindFirst(ClaimTypes.Sid).Value;
            var makerArrayNo = _context.SignMakers.Find(Convert.ToInt32(signMakerId)).ArrayNo;
            ViewData["makerArrayNo"] = makerArrayNo;
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }
        /// <summary>
        /// 制章
        /// </summary>
        /// <returns></returns>
        /// 
        [Authorize(Roles = "SignMaker")]
        [HttpPost]
        public async Task<IActionResult> Create(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"印章生成：印章生成失败|系统未经自检");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"印章生成：印章生成失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var produceSignViewModel = JsonConvert.DeserializeObject<ProduceSignViewModel>(jsonBack);
            if (produceSignViewModel == null)
            {
                logger.Info($"印章生成：印章生成失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"印章生成：印章生成失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, produceSignViewModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"印章生成：印章生成失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            //验证制章人证书
            var produceSignModel = produceSignViewModel.ProduceSign;
            var makerArrayNo = produceSignModel.MakerCertSN;
            var signmaker = await _context.SignMakers.FirstOrDefaultAsync(p => p.ArrayNo == makerArrayNo);
            if (signmaker == null)
            {
                logger.Info($"印章生成：印章生成失败|不存在该制章人");
                return Json(new { state = resultType.Error, message = "不存在该制章人" });
            }

            var produceSigns = _context.ProduceSigns.Where(s => s.UserCertSN.Equals(produceSignModel.UserCertSN, StringComparison.OrdinalIgnoreCase));
            ProduceSign produceSign = null;
            if (produceSigns != null && produceSigns.Count() > 0)
            {
                produceSign = produceSigns.FirstOrDefault();
                produceSign.MakerCertSN = produceSignModel.MakerCertSN;
                produceSign.MakerCertBase64 = produceSignModel.MakerCertBase64;
                produceSign.UserCertBase64 = produceSignModel.UserCertBase64;
                produceSign.UserCertSN = produceSignModel.UserCertSN;
                produceSign.CreateTime = DateTime.Now.ToString();
                produceSign.SealType = produceSignModel.SealType;
                produceSign.SealBase64 = produceSignModel.SealBase64;
                produceSign.SealName = produceSignModel.SealName;
                produceSign.StartTime = produceSignModel.StartTime;
                produceSign.IsAudit = 0;
            }
            else
            {
                //制章
                produceSign = new ProduceSign()
                {
                    MakerCertSN = produceSignModel.MakerCertSN,
                    MakerCertBase64 = produceSignModel.MakerCertBase64,
                    UserCertSN = produceSignModel.UserCertSN,
                    UserCertBase64 = produceSignModel.UserCertBase64,
                    CreateTime = DateTime.Now.ToString(),
                    SealType = produceSignModel.SealType,
                    SealBase64 = produceSignModel.SealBase64,
                    SealName = produceSignModel.SealName,
                    StartTime = produceSignModel.StartTime,
                    EndTime = produceSignModel.EndTime,
                    IsAudit = 0,
                    SealImage = produceSignModel.SealImage
                };
                _context.ProduceSigns.Add(produceSign);
            }
            int res = await _context.SaveChangesAsync();
            if (res > 0)
            {
                logger.Info($"制章人{User.Identity.Name}制作了签章");
                _context.InfoLogs.Add(new InfoLog()
                {
                    UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                    UserName = User.Identity.Name ?? "",
                    CreateDate = DateTime.Now.ToString(),
                    UserType = (int)userType.SignMaker,
                    Remark = $"制章人{User.Identity.Name ?? ""}制作了签章",
                    ManageType = manageType.MakeSign.ToString()
                });
            }
            await _context.SaveChangesAsync();
            logger.Info($"印章生成：印章生成成功|制章人序列号:{produceSignModel.MakerCertSN}|用户CN项:{produceSignViewModel.UserCN}");
            return Json(new { state = resultType.Success, message = "成功制作签章" });
        }

        /// <summary>
        /// 验章
        /// </summary>
        /// <returns></returns>
        [Authorize(Roles = "SignMaker")]
        public IActionResult Verify()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }
        /// <summary>
        /// 验章
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Authorize(Roles = "SignMaker")]
        public async Task<IActionResult> Verify(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"印章验证：印章验证失败|系统未经自检");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"印章验证：印章验证失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var editStrModel = JsonConvert.DeserializeObject<EditStrModel>(jsonBack);
            if (editStrModel == null)
            {
                logger.Info($"印章验证：印章验证失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"印章验证：印章验证失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, editStrModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"印章验证：印章验证失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            logger.Info($"制章人{User.Identity.Name}验证了签章");
            _context.InfoLogs.Add(new InfoLog()
            {
                UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                UserName = User.Identity.Name ?? "",
                CreateDate = DateTime.Now.ToString(),
                UserType = (int)userType.SignMaker,
                Remark = $"制章人{User.Identity.Name ?? ""}验证了签章{editStrModel.ArrayNo}",
                ManageType = manageType.VerifySign.ToString()
            });
            await _context.SaveChangesAsync();
            logger.Info($"印章验证：印章验证成功|制章人序列号:{editStrModel.ArrayNo}|用户CN项:{editStrModel.UserCN}");
            return Json(new { state = resultType.Success, message = "成功验证了签章" });
        }

        /// <summary>
        /// 恢复印章
        /// </summary>
        /// <returns></returns>
        [Authorize(Roles = "SignMaker")]
        public IActionResult Restore()
        {
            var guid = Guid.NewGuid();
            ViewData["ValidateCode"] = guid.ToString();
            HttpContext.Response.Cookies.Append("ValidateCode",
                Convert.ToBase64String(ToolClass.Encrypt(Encoding.UTF8.GetBytes(guid.ToString()))));
            return View();
        }

        /// <summary>
        /// 恢复印章
        /// </summary>
        /// <returns></returns>
        //[HttpPost]
        //public async Task<IActionResult> Restore()
        //{
        //    return Ok();
        //}
        [Authorize(Roles = "SignMaker")]
        public async Task<IActionResult> GetRestoreSeal(string EncryptData)
        {
            if (!Define.IsChecked)
            {
                logger.Info($"印章恢复：印章恢复失败|系统未经自检");
                return Json(new { state = resultType.Error, message = "系统未经自检，请先执行自检后操作" });
            }
            var jsonBack = ToolClass.EncryptTransit(EncryptData);
            //if (string.IsNullOrEmpty(jsonBack))
            //{
            //    return Json(new { state = resultType.Error, message = "参数错误" });
            //}
            if (int.TryParse(jsonBack, out var errorCodeValue))
            {
                var errorCode = (ErrorCode)errorCodeValue;
                logger.Info($"印章恢复：印章恢复失败|错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}");
                return Json(new { state = resultType.Error, message = $"错误码：{errorCodeValue}，错误信息：{ToolClass.GetDescription(errorCode)}" });
            }
            var editStrModel = JsonConvert.DeserializeObject<EditStrModel>(jsonBack);
            if (editStrModel == null)
            {
                logger.Info($"印章恢复：印章恢复失败|数据不存在");
                return Json(new { state = resultType.Error, message = "数据不存在" });
            }
            #region cookie验证
            var guidStr = "";
            if (!HttpContext.Request.Cookies.TryGetValue("ValidateCode", out guidStr))
            {
                logger.Info($"印章恢复：印章恢复失败|cookie未设置，请联系管理员");
                return Json(new { state = resultType.Error, message = "cookie未设置，请联系管理员" });
            }
            var guidFromCookie = Encoding.UTF8.GetString(ToolClass.Decrypt(Convert.FromBase64String(guidStr)));
            if (!string.Equals(guidFromCookie, editStrModel.ValidateCode, StringComparison.OrdinalIgnoreCase))
            {
                logger.Info($"印章恢复：印章恢复失败|cookie不正确，请刷新页面后重试");
                return Json(new { state = resultType.Error, message = "cookie不正确，请刷新页面后重试" });
            }
            #endregion
            _context.InfoLogs.Add(new InfoLog()
            {
                UserId = Convert.ToInt32(User.FindFirst(ClaimTypes.Sid).Value),
                UserName = User.Identity.Name ?? "",
                CreateDate = DateTime.Now.ToString(),
                UserType = (int)userType.SignMaker,
                Remark = $"制章人{User.Identity.Name ?? ""}恢复了印章{editStrModel.ArrayNo}",
                ManageType = manageType.RecoverSign.ToString()
            });
            await _context.SaveChangesAsync();
            logger.Info($"印章恢复：印章恢复成功|制章人序列号:{editStrModel.ArrayNo}|用户CN项:{editStrModel.UserCN}");
            return Ok(await _context.ProduceSigns.Where(s => s.UserCertSN == editStrModel.ArrayNo).OrderByDescending(p => p.Id).Select(s => s.SealBase64)
                .FirstOrDefaultAsync());
            //return Json(new {
            //    state = resultType.Success,
            //    message = "恢复印章成功",
            //    data = await _context.ProduceSigns.Where(s => s.UserCertSN == editStrModel.ArrayNo).Select(s => s.SealBase64)
            //    .FirstOrDefaultAsync()
            //});
        }
    }
}